<?php

/**
 * @Author: Wang chunsheng  email:2192138785@qq.com
 * @Date:   2023-09-19 16:28:58
 * @Last Modified by:   Wang chunsheng  email:2192138785@qq.com
 * @Last Modified time: 2023-09-21 17:04:20
 */

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/5/18
 * Time: 10:46
 */

namespace Common\Exception\Handler;

use Common\Exception\BaseException;
use Common\Models\Enums\ApiResEnums\ErrorCode;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpServer\Response;
use Hyperf\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Throwable;

class BusinessExceptionHandler extends ExceptionHandler
{
    /**
     * @var ContainerInterface
     */
    protected ContainerInterface $container;

    /**
     * @var Response
     */
    protected mixed $response;

    /**
     * @var StdoutLoggerInterface
     */
    protected mixed $logger;

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->response = $container->get(Response::class);
        $this->logger = $container->get(StdoutLoggerInterface::class);
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        if ($throwable instanceof BaseException) {
            $this->logger->warning(format_throwable($throwable));
            return $this->response->error($throwable->getCode(), $throwable->getMessage());
        }

        if ($throwable instanceof ValidationException) {
            $message = $throwable->validator->errors()->first();
            return $this->response->error(ErrorCode::COMMON_ERROR, $message);
        }

        $this->logger->error(format_throwable($throwable));
        return $this->response->error(ErrorCode::SERVER_ERROR, $throwable->getMessage());
    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
